# Flickr Aggregator library - taken from the Typo project.

require 'open-uri'
require 'time'
require 'rexml/document'

# Example:
#
# flickr = Flickr.new('http://www.flickr.com/services/feeds/photos_public.gne?id=40235412@N00&format=rss_200')
# flickr.pics.each do |pic|
#   puts "#{pic.title} @ #{pic.link} updated at #{pic.date}"
# end
#
class MacGalleryAggregation
  include REXML

  def choose(num)
    return pics unless pics.size > num
    bag = []
    set = pics.dup
    num.times {|x| bag << set.delete_at(rand(set.size))}
    bag
  end

  attr_accessor :url, :pics, :link, :title, :description

  # This object holds given information of a picture
  class Picture
    attr_accessor :orig_title, :date, :description, :small_image, :base_image

    def initialize(attrs = {})
      attrs.each do |k, v|
        self.send("#{k}=", v)
      end
    end

    def to_s
      title
    end
    
    def title
      "#{orig_title} - #{date.strftime("%b %Y")}"
    end

    def date=(value)
      @date = Time.parse(value)
    end
    
    def link
      base_image
    end

    def small
      small_image
    end
    def square
      base_image + "/square.jpg"
    end
    def medium
      base_image + "/medium.jpg"
    end
    def large
      base_image + "/large.jpg"
    end
    def full
      base_image + "/web.jpg"      
    end
  end

  # Pass the url to the RSS feed you would like to keep tabs on
  # by default this will request the rss from the server right away and
  # fill the tasks array
  def initialize(url, refresh = true)
    self.pics  = []
    self.url    = url
    self.refresh if refresh
  end

  # This method lets you refresh the tasks int the tasks array
  # useful if you keep the object cached in memory and
  def refresh
    t = Time.now
    open(@url) do |http|
      data = http.read
      # puts "Reading: #{Time.now - t}"
      parse(data)
    end
  end

private

  def parse(body)
    t = Time.now
    xml = Document.new(body)
    channel = xml.get_elements("rss").first.get_elements("channel").first

    self.pics        = []

    channel.each_element("item") do |elem|

      picture = Picture.new
      picture.orig_title       = html_decode(elem.get_elements("title").first.text)
      picture.date        =      elem.get_elements("pubDate").first.text
      picture.small_image       = html_decode(elem.get_elements("iphoto:thumbnail").first.text)
      picture.base_image       = picture.small_image.gsub(/\....\?.*/, "")

      # picture.orig_title       = html_decode(XPath.match(elem, "title/text()").to_s)
      # picture.date        = XPath.match(elem, "pubDate/text()").to_s
      # picture.description = XPath.match(elem, "description/text()").to_s
      # picture.small_image       = html_decode(XPath.match(elem, "iphoto:thumbnail/text()").to_s)
      # picture.base_image       = html_decode(XPath.match(elem, "iphoto:thumbnail/text()").to_s).gsub(/\....\?.*/, "")

      pics << picture
    end
    # puts "Parsing: #{Time.now - t} sec"
  end
  
  def html_decode(s)
    s.gsub("&lt;", "<").gsub("&gt;", ">").gsub("&amp;", "&")
  end
end